package com.sky.loveshop.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sky.loveshop.entity.Shelf;
import com.sky.loveshop.entity.Shop;
import com.sky.loveshop.entity.Sku;
import com.sky.loveshop.entity.exception.BizException;
import com.sky.loveshop.entity.exception.BizExceptionEnum;
import com.sky.loveshop.entity.qo.ShelfQO;
import com.sky.loveshop.entity.vo.AreaShelfVO;
import com.sky.loveshop.entity.vo.ShelfVO;
import com.sky.loveshop.entity.vo.SkuDetailVO;
import com.sky.loveshop.entity.vo.SkuVO;
import com.sky.loveshop.mapper.ShelfMapper;
import com.sky.loveshop.mapper.ShopMapper;
import com.sky.loveshop.service.ShelfService;
import com.sky.loveshop.service.SkuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author xcy
 * @version V1.0
 * @description
 * @date 2024/8/18 0:06
 */
@Slf4j
@Service
public class ShelfServiceImpl implements ShelfService {

    @Autowired
    private ShelfMapper shelfMapper;
    @Autowired
    private ShopMapper shopMapper;
    @Autowired
    private SkuService skuService;

    @Override
    public List<ShelfVO> listShelf(ShelfQO shelfQO) {
        List<ShelfVO> list = shelfMapper.searchAll(shelfQO);
        List<Integer> shopIds = list.stream().map(Shelf::getShopId).collect(Collectors.toList());
        List<Shop> shops = shopMapper.getShopsByIds(shopIds);
        Map<Integer, String> nameMap = shops.stream().collect(Collectors.toMap(Shop::getId, Shop::getName));
        list.stream().forEach(s -> s.setShopName(nameMap.get(s.getShopId())));
        return list;
    }

    @Override
    public PageInfo<ShelfVO> listShelfPages(ShelfQO shelfQO) {
        log.info("listShelfPagesParam ={}", JSONUtil.toJsonStr(shelfQO));
        PageHelper.startPage(shelfQO.getPageNum(), shelfQO.getPageSize());
        List<ShelfVO> shelfList = shelfMapper.searchAll(shelfQO);
        List<Integer> shopIds = shelfList.stream().map(Shelf::getShopId).distinct().collect(Collectors.toList());
        List<Shop> shops = shopMapper.getShopsByIds(shopIds);
        Map<Integer, String> nameMap = shops.stream().collect(Collectors.toMap(Shop::getId, Shop::getName));
        shelfList.stream().forEach(s -> s.setShopName(nameMap.get(s.getShopId())));
        return new PageInfo<>(shelfList);
    }

    @Override
    public ShelfVO getShelfById(Integer id) {
        Shelf shelf = shelfMapper.getShelfById(id);
        Shop shop = shopMapper.getShopById(shelf.getShopId());
        ShelfVO shelfVO = new ShelfVO();
        BeanUtils.copyProperties(shelf, shelfVO);
        shelfVO.setShopName(shop.getName());
        return shelfVO;
    }

    @Override
    public List<Shelf> getShelfListByIds(List<Integer> ids) {
        return shelfMapper.getShelfListByIds(ids);
    }

    @Override
    public Integer addShelf(Shelf shelf) {
        return shelfMapper.insertOne(shelf);
    }

    @Override
    public Integer delShelfById(Integer id) {
        return shelfMapper.delShelfById(id);
    }

    @Override
    public Integer updateShelfById(Shelf shelf) {
        return shelfMapper.updateShelfById(shelf);
    }

    @Override
    public List<AreaShelfVO> getShelfListByShopId(Integer shopId) {
        log.info("getShelfListByShopIdParam shopId={}", shopId);
        List<AreaShelfVO> result = new ArrayList<>();
        // 先获取商店有几个区域
        List<String> allAreaList = shelfMapper.getShelfListByShopId(shopId);
        // 获取区域对应总位置数量(A->140个位置,B->125个位置,C->140个位置......)
        List<AreaShelfVO> noTotal = shelfMapper.getAreaTotalNo(shopId);
        // (area:totalNo)map
        Map<String, Integer> areaNoMap = noTotal.stream().collect(Collectors.toMap(AreaShelfVO::getAreaName, AreaShelfVO::getTotalNo));

        List<AreaShelfVO> levelList = shelfMapper.getAreaLevelGroup(shopId);
        // (area:totalLevel)map
        Map<String, Integer> areaLevelMap = levelList.stream().collect(Collectors.toMap(AreaShelfVO::getAreaName, AreaShelfVO::getTotalLevel));

        for (String area : allAreaList) {
            AreaShelfVO a = new AreaShelfVO();
            a.setAreaName(area);
            a.setTotalLevel(areaLevelMap.get(area));
            a.setTotalNo(areaNoMap.get(area));
            result.add(a);
        }
        return result;
    }

    public List<SkuDetailVO> getIndexByShoIdAndArea(Integer shopId, String area, String keyWords) throws Exception {
        log.info("getIndexByShoIdAndAreaParam shopId={} area={} keyWords={}", shopId, area, keyWords);
        // 根据商店id和区域id获取每一个位置的数据
        List<Shelf> shelfList = shelfMapper.getShelfByShopIdAndArea(shopId, area, keyWords);
        if (CollectionUtil.isEmpty(shelfList)) {
            throw new BizException(BizExceptionEnum.SHOP_AREA_DO_HAVE_SHELF);
        }
        // 层数
        List<Integer> LevelLists = shelfList.stream().map(Shelf::getLevel).distinct().sorted().collect(Collectors.toList());
        // (层数->这一层所有坑位)map
        Map<Integer, List<Shelf>> levelIdentityMap = shelfList.stream().collect(Collectors.groupingBy(Shelf::getLevel));

        List<Integer> shelfIds = shelfList.stream().map(Shelf::getId).collect(Collectors.toList());
        List<SkuVO> skuVOList = skuService.getSkuListByShelfIds(shelfIds);
        if (CollectionUtil.isEmpty(skuVOList)) {
            throw new BizException(BizExceptionEnum.SHOP_AREA_LEVEL_NO_DO_HAVE_SKU);
        }

        // 按层分组
        Map<Integer, List<SkuVO>> levelSkuVOS = skuVOList.stream().collect(Collectors.groupingBy(SkuVO::getLevel));

        ArrayList<SkuDetailVO> list = new ArrayList<>();

        for (int i = 1; i <= LevelLists.size(); i++) {
            SkuDetailVO detail = new SkuDetailVO();
            detail.setLevel(i);
            List<Map<Integer, List<SkuVO>>> skuVOSList = new ArrayList<>();
            List<Shelf> shelfLevelList = levelIdentityMap.get(i);// 第i层货架
            List<SkuVO> levelSkuVOs = levelSkuVOS.get(i);// 每层上的所有商品s

            // (这一层 这一个位置上的多个商品)
            Map<Integer, List<SkuVO>> indexNoMap = levelSkuVOs.stream().collect(Collectors.groupingBy(Sku::getShelfId));

            for (int j = 0; j < shelfLevelList.size(); j++) {
                Shelf shelf = shelfLevelList.get(j);
                List<SkuVO> zList = indexNoMap.get(shelf.getId());

                Map<Integer, List<SkuVO>> map = new HashMap<>();
                List<SkuVO> abc = new ArrayList<>();
                for (int k = 0; k < zList.size(); k++) {
                    SkuVO s = new SkuVO();
                    SkuVO vo = zList.get(k);
                    s.setId(vo.getId());
                    s.setProductId(vo.getProductId());
                    s.setShopId(vo.getShopId());
                    s.setShelfId(vo.getShelfId());
                    s.setBarCode(vo.getBarCode());
                    s.setSalesPrice(vo.getSalesPrice());
                    s.setBuyPrice(vo.getBuyPrice());
                    s.setStockNumber(vo.getStockNumber());
                    s.setStatus(vo.getStatus());
                    s.setProductName(vo.getProductName());
                    s.setPicture(vo.getPicture());
                    s.setShopName(vo.getShopName());
                    s.setShelfName(vo.getShelfName());
                    s.setCategoryId(vo.getCategoryId());
                    s.setCategoryName(vo.getCategoryName());
                    s.setArea(shelf.getArea());
                    s.setLevel(shelf.getLevel());
                    s.setNo(shelf.getNo());
                    s.setPlace(shelf.getArea() + shelf.getLevel() + String.format("%02d", shelf.getNo()));
                    s.setDangerNumber(vo.getDangerNumber());
                    Integer dangerFlag = (vo.getStockNumber() <= vo.getDangerNumber()) ? 1 : 0;
                    s.setDangerFlag(dangerFlag);
                    abc.add(s);
                }
                map.put(shelf.getNo(), abc);
                skuVOSList.add(map);
            }
            detail.setSkuVOSMapList(skuVOSList);
            list.add(detail);
        }
        return list;
    }

    @Override
    public Shelf getShelfByNameAndShopId(String keyWords, Integer shopId) {
        return shelfMapper.getShelfByNameAndShopId(keyWords, shopId);
    }
}
